package com.lumlord.common.database;

import java.lang.reflect.Method;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;

import com.lumlord.common.annotation.mybatis.Master;
import com.lumlord.common.base.ApiController;

/**
 * 读写分离
 * @author GPF
 * @date 2020-5-7 
 *
 */
@Aspect
@Component
@EnableAsync
@Order(-10) // 保证该AOP在@Transactional之前执行
public class DataSourceAop extends ApiController{
	private final String[] masterMethod = { //写操作 关联数据库
			"save",
			"update",
			"set",
			"del",
			"create",
			"register",
			"ins"
			
	};
	
	@Pointcut("@annotation(com.lumlord.common.annotation.mybatis.Master) || execution(* com.lumlord.service.*.*Service.*(..))")
	public void serviceAopDb() { }
	
	@Before("serviceAopDb()")
    public void beforemasterWrite(JoinPoint joinPoint) throws Throwable {
		 String methodName = joinPoint.getSignature().getName();
		 if (StringUtils.startsWithAny(methodName,masterMethod)||getAnnotationMaster(joinPoint)!=null) {
			 DBContextHolder.master();
		 }else {
			 DBContextHolder.slave();
		 }
    }
	
	Master getAnnotationMaster(JoinPoint joinPoint) throws Exception {
		Signature signature = joinPoint.getSignature();
		MethodSignature methodSignature = (MethodSignature) signature;
		Method method = methodSignature.getMethod();

		if (method != null) {
			return method.getAnnotation(Master.class);
		}
		return null;
	}

	
}
 